<?php


namespace app\api\logic;


use app\model\pms\GoodsBrand;
use app\model\pms\GoodsCate;
use app\model\pms\GoodsTag;
use app\model\user\User;
use Carbon\Carbon;
use plugin\coupon\app\model\Coupon;
use plugin\coupon\app\model\CouponReceiveLog;
use support\exception\BadException;
use support\utils\Form;
use support\utils\RandomUtil;
use support\utils\Time;
use think\db\Query;
use think\facade\Db;

class CouponLogic extends \plugin\coupon\app\admin\logic\CouponLogic
{

    public function getCanReceive($uid)
    {


        $list = $this->model->where([
            'status' => Coupon::STATUS_ENABLE,
        ])
            ->select()->toArray();
        $user = [];
        $userCoupon = [];
        if ($uid) {
            $user = User::where([
                'id' => $uid
            ])
                ->field([
                    'group_id',
                    'level_id',
                    'label_ids',
                ])
                ->find();
            $userCoupon = $this->couponReceiveLogModel->where([
                'coupon_id' => array_column($list, 'id'),
                'user_id' => $uid,
                'status' => CouponReceiveLog::STATUS_NO_USED,
            ])
                ->column('coupon_id');
        }


        $goods_category_ids = [];
        $goods_brand_ids = [];
        $goods_tag_ids = [];
        foreach ($list as $key => $item) {
            if ($item['goods_category_ids']) {
                $goods_category_ids = array_merge($goods_category_ids, strToArr($item['goods_category_ids']));
            }
            if ($item['goods_brand_ids']) {
                $goods_brand_ids = array_merge($goods_brand_ids, strToArr($item['goods_brand_ids']));
            }
            if ($item['goods_tag_ids']) {
                $goods_tag_ids = array_merge($goods_tag_ids, strToArr($item['goods_tag_ids']));
            }
        }

        $cate = $goods_category_ids ? GoodsCate::where('id', 'in', $goods_category_ids)
            ->column('name', 'id') : [];
        $brand = $goods_brand_ids ? GoodsBrand::where('id', 'in', $goods_brand_ids)
            ->column('name', 'id') : [];
        $tags = $goods_tag_ids ? GoodsTag::where('id', 'in', $goods_tag_ids)
            ->column('name', 'id') : [];

        foreach ($list as $key => $item) {
            if ($user) {
                if ($item['user_group_ids'] && !in_array($user['group_id'], strToArr($item['user_group_ids']))) {
                    unset($list[$key]);
                    continue;
                }
                if ($item['user_level_ids'] && !in_array($user['level_id'], strToArr($item['user_level_ids']))) {
                    unset($list[$key]);
                    continue;
                }
                if ($item['user_level_ids'] && !array_intersect(strToArr($user['label_ids']), strToArr($item['user_label_ids']))) {
                    unset($list[$key]);
                    continue;
                }
            }
            $cateNames = [];
            $brandNames = [];
            $tagNames = [];
            foreach ($item['goods_category_ids'] as $id) {
                ($cate[$id] ?? "") && $cateNames[] = $cate[$id];
            }
            foreach ($item['goods_brand_ids'] as $id) {
                ($brand[$id] ?? "") && $brandNames[] = $brand[$id];
            }
            foreach ($item['goods_tag_ids'] as $id) {
                ($tags[$id] ?? "") && $tagNames[] = $tags[$id];
            }
            $list[$key]['cateNames'] = implode(',', $cateNames);
            $list[$key]['brandNames'] = implode(',', $brandNames);
            $list[$key]['tagNames'] = implode(',', $tagNames);
            $receive_state = 1;
            if ($userCoupon && in_array($item['id'], $userCoupon)) {
                $receive_state = 2;
            }
            $list[$key]['receive_state'] = $receive_state; //1可领取 2已经领取了还没使用 3不可以领取了
        }
        return array_values($list);
    }

    public function getMyCoupon($uid, Form $form)
    {

        $where = [];
        if ($form['status']) {
            $where[] = ['status', '=', $form['status']];
        }
        $list = $this->couponReceiveLogModel->where([
            'user_id' => $uid,
        ])
            ->where($where)
            ->with([
                'coupon' => function (Query $query) {
                    $query->withoutField([
                        'start_time',
                        'end_time',
                    ]);
                }
            ])
            ->select()
            ->toArray();
        $goods_category_ids = [];
        $goods_brand_ids = [];
        $goods_tag_ids = [];
        foreach ($list as $key => $item) {
            $coupon = $item['coupon'];
            if ($coupon['goods_category_ids']) {
                $goods_category_ids = array_merge($goods_category_ids, strToArr($coupon['goods_category_ids']));
            }
            if ($coupon['goods_brand_ids']) {
                $goods_brand_ids = array_merge($goods_brand_ids, strToArr($coupon['goods_brand_ids']));
            }
            if ($coupon['goods_tag_ids']) {
                $goods_tag_ids = array_merge($goods_tag_ids, strToArr($coupon['goods_tag_ids']));
            }
        }

        $cate = $goods_category_ids ? GoodsCate::where('id', 'in', $goods_category_ids)
            ->column('name', 'id') : [];
        $brand = $goods_brand_ids ? GoodsBrand::where('id', 'in', $goods_brand_ids)
            ->column('name', 'id') : [];
        $tags = $goods_tag_ids ? GoodsTag::where('id', 'in', $goods_tag_ids)
            ->column('name', 'id') : [];

        foreach ($list as $key => $item) {
            $cateNames = [];
            $brandNames = [];
            $tagNames = [];
            $coupon = $item['coupon'];
            foreach ($coupon['goods_category_ids'] as $id) {
                ($cate[$id] ?? "") && $cateNames[] = $cate[$id];
            }
            foreach ($coupon['goods_brand_ids'] as $id) {
                ($brand[$id] ?? "") && $brandNames[] = $brand[$id];
            }
            foreach ($coupon['goods_tag_ids'] as $id) {
                ($tags[$id] ?? "") && $tagNames[] = $tags[$id];
            }
            $list[$key]['cateNames'] = implode(',', $cateNames);
            $list[$key]['brandNames'] = implode(',', $brandNames);
            $list[$key]['tagNames'] = implode(',', $tagNames);
            unset($coupon['id']);
            $list[$key]['start_time'] = Carbon::parse($list[$key]['start_time'])->toDateString();
            $list[$key]['end_time'] = Carbon::parse($list[$key]['end_time'])->toDateString();
            $list[$key] = array_merge($list[$key], $coupon);
        }
        return $list;
    }

    public function receive($uid, $coupon_id)
    {
        $one = $this->model->where([
            'id' => $coupon_id,
        ])
            ->find();
        if (!$one || $one['status'] != Coupon::STATUS_ENABLE) {
            throw new BadException("领券失败,优惠券状态异常");
        }
        if ($one['is_limit_num'] === 1 && $one['total_num'] - $one['received_num'] <= 0) {
            throw new BadException("领券失败,优惠券无库存");
        }

        $userCouponReceiveCount = $this->couponReceiveLogModel->where([
            'coupon_id' => $coupon_id,
            'user_id' => $uid,
        ])
            ->count();
        if ($userCouponReceiveCount >= $one['max_receive_num']) {
            throw new BadException("领券失败,优惠券领取上限");
        }

        if ($one['validity_type'] == Coupon::VALIDITY_TYPE_FIXED) {
            $start_time = Carbon::parse($one['start_time'])->startOfDay()->toDateTimeString();
            $end_time = Carbon::parse($one['end_time'])->endOfDay()->toDateTimeString();
        } else {
            $start_time = Carbon::now()->startOfDay()->toDateTimeString();
            $end_time = Carbon::now()->addDays($one['receive_useful_day'])->endOfDay()->toDateTimeString();
        }


        $user = UserLogic::getUserByCache($uid);
        $this->couponReceiveLogModel->save([
            "code" => RandomUtil::randomStr(10),
            "coupon_id" => $coupon_id,
            "coupon_name" => $one['name'],
            "user_id" => $uid,
            "user_name" => $user['nickname'],
            "start_time" => $start_time,
            "end_time" => $end_time,
        ]);
        $this->model->update([
            'received_num' => Db::raw('received_num+1'),
            'id' => $coupon_id,
        ]);

        $this->handleCouponSetNoStock([
            'id' => $coupon_id,
        ]);
    }

    /**
     * 过期用户的卡券
     */
    public function expiredUsersCoupon()
    {
        CouponReceiveLog::where([
            ['end_time', '<=', Carbon::now()->toDateTimeString()],
            ['status', '=', CouponReceiveLog::STATUS_NO_USED]
        ])
            ->update([
                'status' => CouponReceiveLog::STATUS_EXPIRE,
                'update_time' => Time::now(),
                'expire_time' => Time::now(),
            ]);
    }

    /**
     * 过期卡券配置
     */
    public function expiredCoupon()
    {
        //处理过期卡券
        Coupon::where([
            ['end_time', '<=', Carbon::now()->toDateTimeString()],
            ['validity_type', '=', Coupon::VALIDITY_TYPE_FIXED],
            ['status', 'in', [
                Coupon::STATUS_ENABLE,
                Coupon::STATUS_NORMAL,
            ]]
        ])
            ->update([
                'status' => Coupon::STATUS_EXPIRED,
                'update_time' => Time::now(),
            ]);
        $this->handleCouponSetNoStock();
    }

    public function handleCouponSetNoStock($where = [])
    {
        //处理发完了卡券
        Coupon::where([
            ['status', 'in', [
                Coupon::STATUS_ENABLE,
                Coupon::STATUS_NORMAL,
            ]]
        ])
            ->where($where)
            ->where("is_limit_num =1 and total_num<=received_num")
            ->update([
                'status' => Coupon::STATUS_NO_STOCK,
                'update_time' => Time::now(),
            ]);
    }

}